Appearance
登录后弹窗
本节目标:理解“登录后弹窗”的核心思路,并能把它用于实际开发或面试表达。 好嘞—按你“只给需要调整的片段、且复杂逻辑在上一行注释”的要求,下面是把
(public)/layout.vue里“手机号验证弹窗”相关逻辑精简/强化后的替换片段。照着替换即可,其他不动。
1) 在** \<template\> 里加入弹窗组件挂载点**
> 放在 \<a-layout\> 的最后比较稳:不影响侧栏/头部的层级。
vue
<!-- 复杂逻辑:手机号验证弹窗(受 query: phone_verify=0 控制;组件内部不改路由) -->
<PhoneVerifyModal
v-model:open="phoneVerifyVisible"
@success="onPhoneVerifySuccess"
@close="onPhoneVerifyClose"
/>> 插入位置建议:你已有的 \<router-view /\> 下方、\</a-layout\> 之前。
2) 在 \<script setup\> 顶部 增加 import
> 如果你的弹窗组件路径不同,改成自己的路径即可。
ts
// 复杂逻辑:引入手机号验证弹窗组件
import PhoneVerifyModal from '@/components/phone-verify/PhoneVerifyModal.vue'3) 替换弹窗显隐与回调逻辑(把你现有这几段替换掉)
> 替换你原先的 phoneVerifyVisible 的 watch / success / close 三段。
ts
// 复杂逻辑:是否需要触发验证弹窗(登录 + 未验证 + URL 显式标记)
const needPhoneVerify = computed(() => {
return (
userStore.isLoggedIn &&
userStore.userInfo?.phone_verify === false &&
route.query.phone_verify === '0'
)
})
// 复杂逻辑:弹窗显隐状态(仅由 needPhoneVerify 驱动;避免多处状态源)
const phoneVerifyVisible = ref(false)
// 复杂逻辑:根据路由与用户信息的变更,自动控制弹窗显隐
watch(
needPhoneVerify,
(flag) => {
phoneVerifyVisible.value = flag
},
{ immediate: true },
)
// 复杂逻辑:清除 URL 指定的某个查询参数(保持当前路由名/参数,其它查询不变)
const clearQueryKey = (key: string) => {
const { [key]: _drop, ...rest } = route.query
router.replace({ name: String(route.name || ''), params: route.params, query: rest })
}
// 复杂逻辑:验证成功 -> 更新本地用户信息 + 清理 URL 标记(下次不再弹)
const onPhoneVerifySuccess = () => {
userStore.setUserInfo({ phone_verify: true })
clearQueryKey('phone_verify')
phoneVerifyVisible.value = false
}
// 复杂逻辑:用户手动关闭 -> 仅关闭 UI,不清 URL 标记(下次进入仍会提示)
const onPhoneVerifyClose = () => {
phoneVerifyVisible.value = false
}> 这段把显隐的单一真相收敛到 needPhoneVerify,避免“多个 watch 源”导致的闪烁/不同步。
4) (可选强化)防抖防止频繁闪烁(网络慢时重复开关)
> 如果你遇到用户信息延迟更新导致弹窗闪一下,再加一个微小防抖即可。
ts
// 复杂逻辑:微防抖,避免极短时间内反复开关导致闪烁
let toggleTimer: number | null = null
watch(needPhoneVerify, (flag) => {
if (toggleTimer) window.clearTimeout(toggleTimer)
toggleTimer = window.setTimeout(() => {
phoneVerifyVisible.value = flag
toggleTimer = null
}, 50)
})> 有了这段,就把上面第 3 点 watch(needPhoneVerify, ...) 替换为这段即可(两者选其一)。
5) 删除你原文件中这几处老逻辑(避免冲突)
const phoneVerifyVisible = ref(false)保留(因上方也用了),但删除你原来的:- 对
route.query.phone_verify的watch(...); - 旧的
onPhoneVerifySuccess/onPhoneVerifyClose实现;
- 对
- 页面里其它无关逻辑(侧栏、抽屉、copy header 等)保持不动。
为什么这样改?
- 入口统一:显示与否仅由
needPhoneVerify决定(登录/未验证/URL 标记); - 可控回退:
success清 URL 标记并写回userStore,确保下次不弹; - 用户可拒绝:
close不清 URL 标记,下次进入仍会提示(你的需求); - 避免状态打架:不再同时
watch(query)+watch(meta)多源更新,减少竞态与闪烁; - 与我们在守卫里建议的
phone-verifybeforeEach 完整配合(守卫会在满足条件时把?phone_verify=0自动补上,页面只负责 UI)。
需要我顺手给一个**PhoneVerifyModal.vue 的极简参考外壳**吗?(如 v-model:open、@success、@close 的事件/prop 约定)如果你现有的组件接口不同,我也可以按你现有接口改上面片段。
